package jvm.load;

/**
 * 类会在被使用的时候才加载进入内存。
 * 加载类的时候类中的静态字段会被设置初始值，并在类初始化时设置成具体的值。
 * <p></p>
 * 类加载过程： 加载 -> 验证 -> 准备 -> 解析 -> 初始化 -> 使用 -> 卸载
 *
 * 加载：通过类的全限定名称获取二进制字节流，将二进制字节流转换成方法区运行时的数据结构，并且在内存中（java heap）生成java.lang.Class对象
 *
 * （验证 -> 准备 -> 解析）属于链接过程
 * 验证：检验class正确性
 * 准备：给类的静态变量分配内存空间并且设置初始值
 * 解析：将常量池中的符号引用转换成直接引用
 *
 * 初始化：激活类的静态变量的初试化和静态块的初始化，并且设值成程序员设置的值。相当于赋值并且调用静态块。
 *
 * @author yuqi<307530884@qq.com> <2017/3/23>
 * @version 1.0
 * @since 1.0
 */
public class LoadClass {

    public static void main(String[] args) {

        //
//        ClassA classA = new ClassA();
//
//        System.out.println();
//
//        ClassA.ClassA_inner_1 classA_inner_1 = classA.new ClassA_inner_1();
//
//        System.out.println();
//
//        ClassA.ClassA_inner_1_s classA_inner_1_s = new ClassA.ClassA_inner_1_s();
//
//        System.out.println();

//        ClassB classB = new ClassB();

        //
        try {

            String className = "jvm.load.ClassA";

            /**
             * loadClass(className)内部实际调用的方法是  ClassLoader.loadClass(className,false);
             * 第二个参数表示是否执行resolve the class,表示目标对象是否进行链接，false表示不进行链接
             * 不进行链接意味着不进行包括初始化等一些列步骤，那么静态块和静态对象就不会得到执行
             *
             */
            LoadClass.class.getClassLoader().loadClass(className);

            System.out.println("load class over");

            /**
             * Class.forName(className)内部调用forName0(className, true, ClassLoader.getClassLoader(caller), caller)
             * 第二个参数表示是否初始化
             */
            Class.forName(className);

            System.out.println("forName over");

        } catch (Exception e) {
            e.printStackTrace();
        }

    }


}
